<?php //pack11class

class PropertiesManager {
	
    private static $propertiesByName=array();
    private static $propertiesByGroup=array();
    private static $propertiesByID=array();
    private static $searchableProperties=array();
    private static $levels=array();
    private static $groups=array();
    private static $propertiesDone = false;

    public static function properties() {
        //array_push(Tracer::$traceFrom,__CLASS__);
        return (count(self::$propertiesByID)>0)? self::$propertiesByID:self::setProperties(true);
    }

    public static function getSearchable() {
        if(!self::$propertiesDone) self::setProperties();
        $returnArray=array();
        foreach(self::$searchableProperties as $id) {
            $property=self::getProperty($id);
            if($property) array_push($returnArray,$property);
        }
        return $returnArray;
    }

    public static function idMap() {
        return (count(self::$propertiesByName)>0)? self::$propertiesByName:self::setProperties();
    }

    public static function getProperty($id) {

        //trace($id ." is ".(is_numeric($id)? "Number":"String"));

        if(!self::$propertiesDone) self::setProperties();

        if(is_numeric($id)) {
            if(array_key_exists($id, self::$propertiesByID)){
                return self::$propertiesByID[$id];
            } else {
                //trace("Property {$id} not found!");
                return false;
            }
        } else {
            if(array_key_exists($id, self::$propertiesByName)){
                return self::$propertiesByName[$id];
            } else {
                //trace("Property {$id} not found!");
                return false;
            }
        }
    }

    public static function getGroup($groupNumber) {

        if(!self::$propertiesDone) self::setProperties();

        if(array_key_exists($groupNumber, self::$groups))
            return self::$groups[$groupNumber];

            return array();
    }

    public static function getLevel($levelNumber) {

        if(!self::$propertiesDone) self::setProperties();

        if(array_key_exists($levelNumber, self::$levels))
            return self::$levels[$levelNumber];

            return array();
    }

	private static function setProperties($byID=false) {

        $_properties=MySQL::TABLE_PROPERTIES;
        $_groups=MySQL::TABLE_GROUPS;

        $groupssql=MySQLGet::process("Select * from {$_groups};");
		$sql=MySQLGet::process("Select `s1`.*, `s2`.`system` as `parentName` from {$_properties} `s1` left join {$_properties} `s2` on (`s1`.`parent`=`s2`.`id`) order by `s1`.`position`;");
                //trace(MySQLGet::getQuery());
		$groups=array();
                        $group[0]="free";
			foreach($groupssql as $group) {
				$groups[$group['id']]=$group['system'];
			}
			
			self::$propertiesByName=array();
            self::$propertiesByID=array();
            self::$levels=array();
            self::$levels[0]=array();
            self::$levels[1]=array();
            self::$groups=array();

            foreach($sql as $name=>$property) {
		$item=new Property;
			foreach($property as $field=>$value) {
                            if($field=="group") {
                                if(array_key_exists($value, $groups)) {
                                    $item->group=$groups[$value];
                                    $item->groupNum=$value;
                                } else {
                                    $item->group="free";
                                    $item->groupNum=0;
                                }
                            } else {
                                $item->$field=$value;
                            }
			}

                $item->field=($item->hasValue)? "value".$item->id:"prop".$item->id;
                $item->label="";
            if(is_null($property[LanguagesManager::field()])) {
                foreach(LanguagesManager::getLanguages() as $language) {
                    if(!is_null($property["lang".$language->id])) {
                        $item->label=$property["lang".$language->id];
                    } else {
                        //trace("NULL");
                    }
                }
            } else {
                $item->label=$property[LanguagesManager::field()];
            }

		self::$propertiesByName[$item->system]=$item;
                self::$propertiesByID[$item->id]=$item;
                /*if(is_numeric($item->group)) {
                    if(!is_array(self::$propertiesByGroup[$item->group])) {
                        self::$propertiesByGroup[$item->group]=array();
                    }
                    array_push(self::$propertiesByGroup[$item->group], $item);
                }*/
                if($item->search) array_push(self::$searchableProperties, $item->id);
                
                if(!array_key_exists($item->groupNum, self::$groups)) {
                    self::$groups[$item->groupNum]=array();
                }
                array_push(self::$groups[$item->groupNum],$item);

                if($item->level0) array_push(self::$levels[0], $item);
                if($item->level1) array_push(self::$levels[1], $item);
			}

            self::$propertiesDone=true;

            return ($byID)? self::$propertiesByID:self::$propertiesByName;
	}

    public static function getParent(Property $property) {
        if($property->parent==0) return false;
        if($property->id!=$property->parent) {
            return self::$propertiesByID[$property->parent];
        } else {
            $nextGroup=MySQLGet::process("Select `parent` from ".MySQL::TABLE_GROUPS." where `id`='{$property->groupNum}' limit 1");
            if($nextGroup) {
                $nextParent=MySQLGet::process("Select MAX(`id`) as `id` from ".MySQL::TABLE_PROPERTIES." where `group`='{$nextGroup[0]['parent']}' limit 1;");
                if($nextParent) return self::$propertiesByID[$nextParent[0]["id"]];
            }
            return false;
        }
    }

    public static function getChild(Property $property) {
        
    $nextChild=MySQLGet::process("Select `id` from ".MySQL::TABLE_PROPERTIES." where `parent`='{$property->id}' and `id`!='{$property->id}' limit 1");
        if(!$nextChild) {
            //trace("Next child not found");
             $nextGroup=MySQLGet::process("Select `id` from ".MySQL::TABLE_GROUPS." where `parent`='{$property->groupNum}' limit 1");
             if($nextGroup) {
                 //trace("Next group found");
                 $nextChild=MySQLGet::process("Select `id` from ".MySQL::TABLE_PROPERTIES." `t` where `t`.`parent`=`t`.`id` and `t`.`group`='{$nextGroup[0]["id"]}' limit 1");
                 //trace(MySQLGet::getQuery());
                 if($nextChild) {
                     $child=PropertiesManager::getProperty(0+$nextChild[0]["id"]);
                    //trace("First child from next group found:  ".$child." return child");
                    return $child;
                 } else {
                     //trace("next group found, next child not found -> return false");
                     return false;
                 }
             } else {
                 //trace("next group not found -> return false");
                 return false;
             }
         } else {
             $child=PropertiesManager::getProperty(0+$nextChild[0]["id"]);
             //trace("Next child found: ".$child. " return child");
             return $child;
         }

        return false;
    }

    public static function definedSQLFor(Property $current) {
        $resultArray=array();
        foreach(PropertiesManager::properties() as $property) {
            if($current==$property) return (count($resultArray)>0)? implode(" AND ",$resultArray):false;
            if($property->value) {
                array_push($resultArray,"`".$property->field."`='".$property->value."'");
            }
        }

        return (count($resultArray)>0)? implode(" AND ",$resultArray):false;
    }

    public static function traceAllProperties() {
            $str="";
            foreach(self::properties() as $property) {
                if(is_numeric($property->value)) $str.=$property->system.":".$property->value."; ";
            }
            //trace("PROPERTIES: ".$str);
    }

    public static function updateProperties() {
        self::$propertiesDone=false;
        self::setProperties();
    }
	
}

?>